﻿using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Web.Routing;
using Inovout.Data.Domain;

namespace Inovout.Web.Mvc
{
    public class RemoteAttributeAdapter<TAttribute> : DataAnnotationsModelValidator<TAttribute> where TAttribute : ValidationAttribute
    {
        public RemoteAttributeAdapter(ModelMetadata metadata, ControllerContext context, TAttribute attribute)
            : base(metadata, context, attribute)
        {
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            RouteData = new RouteValueDictionary();

            RouteData["controller"] = DataObjectTypeDescriptor.Get(base.Metadata.ContainerType).DeclaringType.Name;
            RouteData["action"] = "Validate";

            yield return new ModelClientValidationRemoteRule(Attribute.FormatErrorMessage(base.Metadata.GetDisplayName()),
                GetUrl(base.ControllerContext), HttpMethod,
                FormatPropertyForClientValidationAdditionalFields(base.Metadata.PropertyName));
        }
        public string FormatPropertyForClientValidationAdditionalFields(string property)
        {
            string delimitedAdditionalFields = "*." + property;

            delimitedAdditionalFields += ",*.Id";

            return delimitedAdditionalFields;
        }
        public string HttpMethod
        {
            get { return "POST"; }
        }

        protected virtual RouteCollection Routes
        {
            get { return RouteTable.Routes; }
        }
        protected RouteValueDictionary RouteData { get; private set; }

        protected virtual string GetUrl(ControllerContext controllerContext)
        {
            var pathData = Routes.GetVirtualPathForArea(base.ControllerContext.RequestContext,
                                                        null,
                                                        RouteData);

            return pathData.VirtualPath;
        }
    }
}
